package cn.tedu.springbootdemo.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;

//@Aspect
//@Component
public class AroundTestAspect {
    /**
     * @Around 环绕通知，围绕目标方法进行执行
     * @Around 是万能通知，可以代替其他4个通知
     * @param point 连接点
     * @return 返回目标方法处理结果
     * @throws Throwable 抛出业务方法执行异常
     */

    @Around("bean(userServiceImpl)")
    public Object testAround(ProceedingJoinPoint point) throws Throwable {
        /**
         * 使用注意事项：
         * 1.@Around的连接点类型ProceedingJoinPoint ，表示被执行的方法
         * 2.point.proceed();表示执行连接点方法
         *  ---如果不执行，就意味着连接点方法被放弃！这种行为可能是一个有害行为，一般都是要执行
         *  ---返回值就是连接方法的返回值，原则上要作为当前方法的返回值，可以在AOP方法中对这个返回值进行加工处理
         *     不过不建议，因为这个可能是一个危险的行为
         *  ---point.proceed()的异常就是连接点方法执行异常，如果进行拦截处理，就意味着影响了异常处理的流程
         *  3.@Around的功能强大，可以处理返回值，可以处理异常，可以在切入点方法前嵌入代码，也可以在切入点方法之后嵌入代码
         */
        try {
            System.out.println("在目标方法执行之前执行");
            //调用目标业务方法
            Object proceed = point.proceed();
            System.out.println("在目标方法执行之后执行");
            return proceed;
        }catch (Exception e){
            System.out.println("执行目标方法出现异常之后执行");
            throw e;
        }finally {
            System.out.println("执行目标方法，无论是否出现异常");
        }
    }
}
